home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / lib / tex / textyl / textyl.shar8.Z / textyl.shar8
Encoding:
Text File  |  1987-08-10  |  56.0 KB  |  1,103 lines

  1. #!/bin/sh
  2. # to extract, remove the header and type "sh filename"
  3. if `test ! -d ./doc`
  4. then
  5.   mkdir ./doc
  6.   echo "mkdir ./doc"
  7. fi
  8. if `test ! -s ./doc/TYLMAN.05`
  9. then
  10. echo "writing ./doc/TYLMAN.05"
  11. cat > ./doc/TYLMAN.05 << 'E_O_F'
  12. \chapter{When Things Go Wrong}
  13. Despite the best of examples and directions about careful typing of
  14. \hbox{|\special|} strings, there are times when \TT will
  15. get upset and complain about some situation or input. Fortunately, \TT can
  16. continue from most of them (like missing or incorrect parameters), and 
  17. just report them in the |.tlog| log-file\index{{\tt .tlog}
  18. file}\index{{\TT}, {\tt .tlog} log-file}
  19. for you.\index{{\TT}, error handling} An example run of \TT might look
  20. like:\filbreak
  21. \begin{verbatim}
  22.   >textyl
  23.   This is TeXtyl, version ...
  24.    DVI-input File Name: myfile.dvi
  25.    DVI-output File Name :
  26.   (different than input name)[default of myfile.tyl]
  27.    [1] [?2]
  28.   Output written on myfile.tyl
  29.   Log written on myfile.tlog
  30.   Some error(s) occurred. Please check Logfile for details.
  31.   Assume that the outputfile is incorrect
  32. \end{verbatim}\filbreak
  33. Rather than annoy you at the terminal with long error messages, \TT puts a 
  34. |?|\index{{\tt ?} flag} mark to indicate that some error happened. Since it wrote the 
  35. |.tyl|\index{{\tt .tyl} file} output file, \TT must have recovered\index{{\TT}, error recovering}
  36. well enough to finish its job,
  37. but the output probably does not look right. The |.tlog| file might look
  38. like\filbreak
  39. \begin{verbatim}
  40. This is TeXtyl, Version blah...
  41. Reading File: myfile.dvi
  42.  [1] [
  43. Error in fig# 1 on page 2
  44. Arc Thickness not found. Setting to 1
  45. 2]
  46. Output written on myfile.tyl
  47. Log written on myfile.tlog
  48. \end{verbatim}\filbreak
  49. \noindent which was just a missing parameter to the |\special{tyl arc ...}| string.
  50. You will  have to re-edit the file and insert the correct thickness.
  51. \index{{\TT}, error messages}
  52. All the error messages that are written to the |.tlog| file try to pin down
  53. the error to the figure number on the error-containing page. These
  54. references to the position of the error
  55. come from the $n^{\rm th}$ figure on the page (the $n$ count is relative to
  56. each page, and starts from 1), and the page number is from {\TeX}'s
  57. |\count0| register that enumerates pages.
  58.  Sometimes \TT
  59. cannot always determine the exact figure on the page
  60. (e.g., if we forget to close a figure definition with an
  61. |endfigure|), and so estimates at least the bad page in question. For the most
  62. part, the error is a just missing parameter,
  63.  or a bad parameter to a |\special| string being read by \TTN.\par\filbreak
  64.  
  65.  However, there are a larger number of errors that \TT
  66. found ``surprising'' \index{errors, internal}\index{surprise errors}
  67. and so marks these errors on your screen as |?! |.\index{{\tt ?!} flag} Most
  68. of these internal errors are based on the functionality of {\DVI}type 
  69. concerning {\smallrm TFM} information, and the structure and commands
  70. of the {\DVI} file being read. \TTN, like {\DVI}type, will complain, and 
  71. possibly roll over and die gracefully.\par\filbreak
  72.  
  73. The other ``surprising''  errors that \TT might complain about are really
  74. internal to \TTN, and constitute a bug,\index{{\TT}, simple problem} or just a
  75. compile-time constant that is too small. These easily-fixed surprises are
  76. \begin{itemize}
  77. \item |too many dvistrings|. This page required more {\DVI} bytes than usual.
  78.  Have your local maintainer\index{local
  79. maintainer} increase the size of the internal buffer used for storing a
  80. page's {\DVI} bytes.
  81. \item |too many spline segments required|.  The spline you tried to set might
  82. be too large/long for the space allocated for a spline's description.
  83. That size is also a compile-time constant. \TT
  84. will reduce the number of control points that it interpolates so that you
  85. can at least get the output, and so that it does not die ungracefully.
  86. \item |figure definition not closed at end of page|. You forgot a
  87. |\special{tyl endfigure}| command in some figure definition on the page. \TT
  88. will not typeset that figure, and will go on to the next page.
  89. \end{itemize}\par\filbreak
  90. There are also some down-deep errors that could potentially (although
  91. doubtfully) show up. These
  92. are probably some error in the vector fonts being referenced by
  93. \TTN.\index{{\TT}, serious problems}
  94. \begin{itemize}
  95. \item |min radius of vector font is zero|. The referenced vector font's
  96. {\smallrm TFM} information reported that the font's radius size
  97. is smaller than it was designed to be.
  98.  \TT will make a temporary fix so that it can
  99. continue, but the output figure will be wrong. Have the local maintainer
  100. re-check the vector fonts.
  101. \item |bad dydx|. This is a rare problem. Somewhere, the code to typeset a
  102. diagonal line segment referenced an impossible $dy/dx$ combination, and cannot find
  103. any vector character to fit. \TT will continue, but you may see a
  104. tiny glitch in your figure.
  105. \item |dx is too big/small|, |dy is too big/small|. This is a problem. For
  106. some reason, a distance was referenced that is out of the range of the 
  107. 32-bit representation of integers. This really should never happen.
  108. \end{itemize}
  109.  
  110. For the most part, \TT can recover from errors that it encounters, and give
  111. a brief summary in the |.tlog| file. Other errors have to do with {\smallrm
  112. TFM} file information, and are outside the scope of \TT to handle
  113. gracefully. The most serious ``surprise'' errors are bugs, and you should
  114. report them directly to me with a copy of the |.tex| file, or at least a
  115. detailed printout from {\DVI}type of the |.dvi| file processed by \TTN.\par
  116.  
  117. \Makeodd
  118. E_O_F
  119. else
  120.   echo "will not over write ./doc/TYLMAN.05"
  121. fi
  122. chmod 644 ./doc/TYLMAN.05
  123. if [ `wc -c ./doc/TYLMAN.05 | awk '{printf $1}'` -ne 5308 ]
  124. then
  125. echo `wc -c ./doc/TYLMAN.05 | awk '{print "Got " $1 ", Expected " 5308}'`
  126. fi
  127. if `test ! -s ./doc/TYLMAN.06`
  128. then
  129. echo "writing ./doc/TYLMAN.06"
  130. cat > ./doc/TYLMAN.06 << 'E_O_F'
  131. \chapter{Design Details}
  132.  The top-level of \TT is taken directly from the
  133.  {\DVI}type\cite{dvitype}\index{DVItype}
  134.  program, with a few
  135. modifications. Most of the diagnostic functionality of {\DVI}type is
  136. maintained, but without the user interface (\TT assumes it is supposed to 
  137. process all the pages).
  138.   A ``hook'' was inserted into
  139. the program to handle the {\TeX}
  140. |\special|s\index{handling specials}\index{specials, handling by {\TT}} 
  141. that \TT understands
  142. (hereafter, ``special'' will refer only to those commands that 
  143. \TT  understands---other |\special|s are ignored, and simply output 
  144. to the {\DVI} file without\index{specials}
  145. modification).\index{DVI file}
  146.   The {\DVI}type code was used  mostly for its keeping\index{DVI
  147. position coordinates}
  148. track of the current {\DVI}\  {\bf h} and {\bf v} position coordinates
  149. on a page, and handling {\smallrm TFM} information\index{TFM information}.\par
  150.  
  151. Basically, as \TT slurps in a {\DVI} file, it processes 
  152. ``normal'' commands
  153. in a normal way (i.e., just keeping track of positions and counters).
  154.  When it reads a |\special| string, it tries to interpret the parameters
  155. and expand the special, producing 
  156.  commands to typeset the graphic using characters from special fonts.
  157.  
  158. The result is a transformed {\DVI} file that now contains
  159. ``normal'' (i.e., non-special, `put-that-character-there') dvi-commands
  160. as far as \TT can tell, after taking care of new font definitions
  161. and doing any bookkeeping of counters and internal references.\par
  162.  
  163. \section{Vectors}
  164. \label{vectors}
  165. Several design decisions\index{design decisions} were made to give \TT  the ability to
  166. typeset the graphics of the complexity that we desire. This ability is
  167. intrinsically bound to the fonts to be used, and the way that we use them.
  168. For this project, I had to create a font of short, oriented line segments\index{vector font}.
  169. This was to minimize the amount of information required to typeset a
  170. curve. One could address each pixel of the virtual device to draw the graphic
  171. (putting hundreds of periods from a font), but that is not
  172. device-independent, and the
  173. amount of data is huge in comparison to using line segments.
  174.  These line
  175. segments can be connected together rather smoothly to give the appearance of
  176. a continuous line segment or curve.\par
  177.  Using this scheme, described by Nelson
  178. and Saxe\index{Nelson{,} Bruce}\index{Saxe{,} James}
  179.  at Carnegie-Mellon University\cite{nelson-saxe}, I am able to typeset the correct
  180. character corresponding to the desired length and angle. I modified their
  181. font those
  182. angles cover the first and fourth cartesian quadrant system,
  183. \index{vector font, range of angles}
  184. and whose vectors are from the origin to points clockwise along the perimeters
  185. of semisquares of decreasing radii\label{semisquare}. They use this scheme in order to use the
  186. longest vectors\index{vector font}\index{vectors, typesetting with}
  187.  possible for a given distance (thus minimizing the number of
  188. characters to typeset), and also have shorter vectors for use in tightly
  189. curving lines. They use a semisquare (rather than a semicircle)
  190.  for a quick line-tangent intersection test in their algorithm to decide the maximum
  191. length vector to use that has a satisfactory variance from the tangent to the
  192. line.
  193. I really must give correct thanks to Dario Giuse\index{Giuse{,} Dario}
  194.  at C-MU\cite{dario} for first
  195. implementing the vector-font typesetting code that I subsequently modified
  196. for \TTN.\par
  197.  
  198.  I modified the  vector font for use with
  199. Metafont~79\cite{knuth-mf}, and was able to describe it 
  200. in a device-independent manner. Because of the limitations
  201. of\index{Metafont, limitations}
  202. Metafont~79's\index{Metafont}\index{vector font, dimensions}
  203. and {\TeX}'s representation of character heights and depths, I could not accurately
  204. describe the character dimensions in such a way that I could leave the
  205. low-level typesetting details to {\TeX} 
  206. through its idea of {\smallrm TFM} information. Thus, \TT has to take
  207. care of the details of calculating the correct dimensions for each character
  208. of each vector font. This calculation is done,
  209.  however, only as a particular font is first
  210. required, and the dimensions\index{vector font, computing dimensions}
  211.  are computed on-the-fly using the group of
  212. parameters found in the {\smallrm TFM} file that we have defined for our own
  213. use. After this initial parameter calculation, subsequent references to that
  214. font's {\smallrm TFM} information is accessible via a caching scheme.
  215.  The fonts contain such information as the measure of the maximum-length
  216. vector of the font, and the height and width of the pen used to draw the
  217. font ({\it all in scaled points}). \par
  218.  
  219. Current plans for the vector fonts are for sizes in the range from about 1
  220. to 12 ``pixels'' for each of the three types of Metafont pens (circular,
  221. flat horizontal, and flat vertical).\index{vector font, sizes}\index{vector
  222. font, types} The fonts are
  223. actually device-independent in size, as our ``pixel'' is measured in
  224. absolute units of 16384 $(2^{14})$ 
  225. scaled-points\index{vector font, pixelsize}. However, there is a step within
  226. Metafont~79 that insures that the vector size is an odd-number of
  227. physical pixels computed at the final output-resolution. This is to avoid
  228. some discretization errors and the accompanying aliasing artifacts.
  229.  I expect the vectors drawn \index{vector font, pen-types}
  230. with circular pens (the ``cvec'' fonts)\index{vector font, cvec} to be the 
  231. most utilized.  Their
  232. endpoints are rounded and are positioned to coincide
  233.  so that the segments overlap slightly and
  234. meet up gracefully producing a smoother curve.  Here are some examples of
  235. circular, horizontal, and vertical pens that can be used for 
  236. different effects:\label{vect-pens}\index{vector font, pens, example}\par 
  237. \noindent\hskip 1in\begintyl{35mm}[1in]
  238. \special{tyl beginfigure} 
  239. \special{tyl line m 10  c 5 5 10 30}
  240. \special{tyl line m 10  h 15 5 27 30}
  241. \special{tyl line m 10  v 30 15 45 23}
  242. \special{tyl endfigure}
  243. \endtyl\par 
  244.  
  245. \medskip
  246. {\bf Beams}\par
  247. A similar scheme is used for the beam characters found within the music
  248. fonts\index{beam font}\index{music font}.  The beam characters are in two types
  249.  (those for grace notes, and\index{beam font, types}
  250. those for regular notes) for the staff sizes\index{staff sizes} of music (numbered 0
  251. down to 8). See also \cite{ross}.\index{beam font, sizes}\label{beam-chars-sizes}
  252.  The font is also a set of short line-segments that will be
  253. connected to create a beam (some other program will have to know about the
  254. details of describing how to attach stems from the beams down to the notes).
  255. However, the beam characters are different\index{beam font, difference from vector font} from the vector fonts in that
  256. each staff size of music has one particular size of beam
  257. characters\index{beam font, relation to staff size}
  258. associated with it.\par
  259.  
  260.  The beams are designed\index{beam font, design} to appear as if they are drawn
  261. with a flat-edged pen held perpendicular to a ruler (at all orientations).
  262. When a vertical pen is drawn along a path, the actual cross sectional
  263. distance of the line segment decreases with the angle (i.e., it is thickest
  264. when drawn along a line at zero degrees from the horizontal, and thinnest as
  265. it is drawn along a line approaching $\pm 90$ degrees). The way to maintain
  266. the appearance of consistent thickness of the line segments at all drawn
  267. angles is to actually {\it increase\/} the ``height'' of the vertical pen as
  268. a function of the angle from the horizontal. This function was geometrically
  269. derived to be the {\it secant\/} of the angle, which yielded in a scaling
  270. factor to apply to the original definition of the vertical pen's height.\par
  271.  
  272. Another difference from the vector fonts is that the beam characters do not
  273. have to cover as large a angular range. The angles from the horizontal are
  274. less than 45 degrees on the average,\index{beam font, range of angles}
  275.  and the lengths of the beam characters\label{beamsizes}
  276. are no smaller than the width of a quarter note for that staff size. The
  277. current implementation defines the beam characters in four groups per staff
  278. size: regular beams in lengths\index{beam font, lengths}
  279.  of 1.0 and 1.5 quarter-note-lengths, and
  280. grace-note beams in lengths of 0.5 and 0.66 grace-note-lengths.\par
  281.  
  282.  The scheme
  283. of typesetting is similar to that of the vectors, but an added constraint is
  284. resolved. Since the beam characters use a slightly smaller set of fixed angles from
  285. the horizontal,\index{beam font, constraints}
  286. we have to choose the best beam character to use such that we use
  287. the maximum length beam character {\it and\/}  try to obtain the least
  288. deviation from the angle requested to fit the beam font.
  289.   The dimensions of these beam characters
  290. are computed only as each music font is required, and a caching scheme
  291. is maintained to avoid unnecessary re-loading of font information and
  292. subsequent definition in the {\DVI} file.  \par
  293.  
  294. \section{Splines}
  295. \label{splines}\index{splines, families}A second decision\index{design decisions} that I made
  296.  for the current implementation of this system
  297. was to use Catmull-Rom\cite{cagd} splines as the default instead of B-splines.\index{splines, default type} The
  298. reasons for this are two-fold: (1) Catmull-Rom splines\index{Catmull-Rom splines} are of the same
  299. family as B-splines, but are {\it guaranteed} to produce a smooth curve {\it
  300. through} the control points, whereas B-splines only approximate within the
  301. convex-hull described by the control points.  Therefore, Catmull-Rom splines
  302. are a true interpolant; and (2) when dealing with the ties and slurs,\index{ties}\index{slurs} the
  303. user wants the curve to go through the five points that he specifies (left,
  304. middle and right points). With B-splines, he would have to {\it estimate}
  305. the position of the middle control points in order to get the curve  to be
  306. in the correct position.  Catmull-Rom  and Cardinal splines are just
  307. as easy to calculate, and usually achieve the effects that we need.\par
  308.  
  309. I have also experimented with operations on the B-splines to achieve true
  310. interpolation. This method was described by Barsky and Greenberg\cite{barsky}
  311.  describing how to re-compute B-spline control-points
  312. so\index{B-splines, recomputing points}
  313. that the resulting spline would interpolate through desired points (inverse
  314. interpolation)\index{splines, inversion}\index{splines, interpolation}.
  315.  It actually does not require very hairy mathematics. 
  316. Arcs and circles are implemented\index{arcs, representation}
  317.  using this spline primitive. The arc\index{arcs, control points}
  318. control-points are computed (or pre-computed in the case of circles,
  319. \index{circles, control points} and\index{circles, representation}
  320. ellipses\index{ellipses} which are just scaled circles) 
  321. and then are used in the inversion
  322. procedure so that the resulting B-spline passes smoothly {\it through\/}
  323. those original points. We will later describe further this usefulness of
  324. implementing various graphic objects using lower-level primitives.\par
  325.  
  326. I also use the Catmull-Rom interpolation when computing the different
  327. thick\-nes\-ses\index{line thickness} along both the tie/slurs and the var\-iable-thick\-ness splines
  328. (``ttsplines'')\index{ttspline}\index{ttspline, line thicknesses}.
  329.  I need to interpolate from the current control-point's
  330. thickness along the curve to the next control-point's thickness, and can do
  331. this smoothly by using the interpolation methods available when computing
  332. the splines anyway.\par
  333.  
  334. Since we have the ability to draw splines of varying thickness, we can
  335. easily implement ties and slurs\index{slurs} (those long
  336.  arcs connecting groups of notes\index{tieslur, implementation}
  337. on a musical score), since they are splines of usually five control points,
  338. having the specified {\it minthick\/} thickness at the left and right, and
  339. {\it maxthick\/} thickness in the middle. \par
  340.  
  341. \Makeodd
  342. E_O_F
  343. else
  344.   echo "will not over write ./doc/TYLMAN.06"
  345. fi
  346. chmod 644 ./doc/TYLMAN.06
  347. if [ `wc -c ./doc/TYLMAN.06 | awk '{printf $1}'` -ne 11870 ]
  348. then
  349. echo `wc -c ./doc/TYLMAN.06 | awk '{print "Got " $1 ", Expected " 11870}'`
  350. fi
  351. if `test ! -s ./doc/TYLMAN.08`
  352. then
  353. echo "writing ./doc/TYLMAN.08"
  354. cat > ./doc/TYLMAN.08 << 'E_O_F'
  355. \chapter{Future Extensions}
  356. Given  a little time, one could extend\index{extensions} the current set of graphic
  357. primitives in \TTN, such as:
  358. \begin{itemize}
  359. \item simpler-appearing macros,
  360. \item  regular polygons (all
  361. easily built upon currently-existing primitives),
  362. \item oriented arrows 
  363. \item line-pattern filled figures, 
  364. \item a more general method of defining and instancing symbol definitions.
  365. \end{itemize}
  366.  I am still experimenting with two
  367. methods of adequately computing the smoothest interpolation of thicknesses
  368. along the length of the slur.  When the thickness for a particular segment
  369. of the curve have been determined, we check to see if that thickness is in a
  370. subset of vector-font sizes.  If so, we can use it as-is; otherwise, we have
  371. to clamp\index{clamping} that thickness to fit in the subset.  The only problem is that
  372. achieving a super-smooth interpolation along the curve's thicknesses might
  373. require a large number of vector fonts to be loaded---sometimes stressing
  374. the printing\index{output device} device's capabilities.  I still have to experiment to find a
  375. reasonable subset of these sizes that can be used and still achieve adequate
  376. results.\par
  377.  
  378.  I wrote this program with the intention of ease
  379. of extensibility for additional ``primitives'' to be built on top of the
  380. functionality provided by \TTN.
  381.  I have also interfaced  \TT with
  382.  Dario Giuse's\index{Giuse{,} Dario} graphic drawing program 
  383.  {\it DP\/}  that he 
  384. wrote at  C-MU\cite{dario}. It is smart enough to represent its graphics primitives 
  385. in files as a list of text-strings, and is now able to output the |\special|
  386. strings, specifying the width and height of the created figure.
  387.  Converting the files of the MacDraw program to yield
  388. {\smallrm ASCII} strings is potentially possible, too.
  389. In either case, such strings are  be easily converted to
  390. |\special| command strings for \TT to work on.\par
  391. \Makeodd
  392. \appendix
  393. E_O_F
  394. else
  395.   echo "will not over write ./doc/TYLMAN.08"
  396. fi
  397. chmod 644 ./doc/TYLMAN.08
  398. if [ `wc -c ./doc/TYLMAN.08 | awk '{printf $1}'` -ne 1912 ]
  399. then
  400. echo `wc -c ./doc/TYLMAN.08 | awk '{print "Got " $1 ", Expected " 1912}'`
  401. fi
  402. if `test ! -s ./doc/TYLMAN.09`
  403. then
  404. echo "writing ./doc/TYLMAN.09"
  405. cat > ./doc/TYLMAN.09 << 'E_O_F'
  406. \chapter{{\TeX}tyl Summary}
  407. Let's summarize the abilities and requirements of \TTN . First of all, we
  408. have to put an |\input{textyl}| near the start of the document (at least
  409. before our first invocation of a |\special{tyl ...| command). This loads the
  410. macros that we need to create space for our figure, and to set up the right
  411. environment for \TTN .\par
  412.  
  413. Once the macros have been loaded, when we want to set a figure (or even a
  414. single \TT primitive), we must place the primitives within an environment
  415. started  by
  416. \hbox{|\begintyl{|\Prm{vertsize}|}[|\Prm{horizsize}|]|}
  417.  and finished by |\endtyl|. Here,
  418. the required parameter,\Prm{vertsize}, determines the vertical
  419. size of the box that \TT will create for our figure to be placed in. If we
  420. do not need extra space, we put in |0pt| or some similar zero-length
  421. dimension. The optional parameter,\Prm{horizsize}, will add a non-zero width
  422. to the box that |\begintyl| creates for us. It is {\it crucial\/} that there
  423. is {\it no\/} space between the |}| and |[| characters of the |\begintyl|
  424. invocation if we decide to use the optional horizontal width specification.
  425. Otherwise, things may go awry for this figure. Also, we are responsible for
  426. any offsets that we may need before the figure is placed. We can achieve
  427. this through |\hskip| and |\vskip| calls in \TeX\ , or |\hspace| and
  428. |\vspace| calls in \LaTeX.\index{space}
  429. \index{{\TeX}}\index{{\LaTeX}}\index{{\TeX} commands}\par
  430.  
  431. The types of primitives that we may place within the |\begintyl| and
  432. |\endtyl| pair are summarized here, without their surrounding
  433.  |\special{tyl | -- |}|, nor any extra delimiting punctuation (like commas).
  434. \begin{verse}
  435. {\tt beginfigure} \sOpt{meas} \sOpt{xfm}\ 
  436. {\leavevmode\hbox{$\>\lbrack${\tt W}$\>\langle wid\/\rangle\,
  437. \langle ht\rangle\,\rbrack\,$}}
  438. {\leavevmode\hbox{$\>\lbrack${\tt F}$\>\langle wid\/\rangle\,
  439. \langle ht\rangle\,\rbrack\,$}} \mbox{\it which opens the environment}
  440.  
  441. {\tt endfigure}\mbox{\it \ \ which closes the environment}
  442.  
  443. {\tt line} \sOpt{meas}\sOpt{xfm} \Prm{thick}
  444. \sOpt{vect}{\leavevmode\hbox{$\>\lbrack${\tt L}$\>\langle style\rangle\,\rbrack$}}
  445.  $ x_{\rm l}\> y_{\rm b}\> x_{\rm r}\> y_{\rm t}$
  446.  
  447. {\tt spline} \sOpt{meas}\sOpt{xfm}\Prm{thick}
  448. \sOpt{vect}{\leavevmode\hbox{$\>\lbrack${\tt L}$\>\langle style\rangle\,\rbrack$}}
  449. \sOpt{spltype}\\
  450. \hspace*{2em}\sOpt{closure}
  451. {\leavevmode\hbox{$\>\lbrack${\tt X}$\>\langle thick\rangle\,\rbrack$}}
  452. \Prm{numpts}\mbox{\it the x-y points}
  453.  
  454. {\tt ttspline} \sOpt{meas}\sOpt{xfm}
  455. \sOpt{vect}{\leavevmode\hbox{$\>\lbrack${\tt L}$\>\langle style\rangle\,\rbrack$}}
  456. \sOpt{spltype}\\
  457. \hspace*{2em}\sOpt{closure}
  458. {\leavevmode\hbox{$\>\lbrack${\tt X}$\>\langle thick\rangle\,\rbrack$}}
  459. \Prm{numpts} \mbox{\it points} \mbox{\it thicknesses}
  460.  
  461. {\tt arc} \sOpt{meas}\sOpt{xfm} \Prm{thick}\sOpt{vect}
  462. {\leavevmode\hbox{$\>\lbrack${\tt L}$\>\langle style\rangle\,\rbrack$}}\Prm{radius}\\
  463. \hspace*{2em}{\leavevmode\hbox{$\>\lbrack${\tt @}$\>\langle cent_x\rangle\,
  464. \langle cent_y\rangle\,\rbrack$}}\Prm{startAng} \Prm{stopAng}
  465.  
  466. {\tt label} \sOpt{meas}
  467. \Prm{face}$\;x \> y$ \mbox{{\tt "}\Prm{string}{\tt "}}
  468.  
  469. {\tt tieslur} \sOpt{meas} \Prm{minthick}\Prm{maxthick}
  470. \Prm{numpts}\mbox{\it points}
  471.  
  472. {\tt beam} \sOpt{meas} \Prm{staffsize}
  473. \sOpt{beamtype} $x_1 \> y_1\> x_2\> y_2$
  474.  
  475. where:
  476. \end{verse}
  477. \begin{description}
  478. \item[meas] specifies units of length for this primitive. One of |S|,|P|, or
  479. |M| indicates scaled-points, printers-points, and millimeters, respectively.
  480. Defaults to printers-points.
  481.  
  482. \item[xfm] specifies a transformation to be applied. It is of the form\\
  483. \mbox{{\tt T}\Prm{sx}\Prm{sy}\Prm{tx}\Prm{ty}\Prm{rot}}, where {\it sx\/} and
  484. {\it sy\/} are for scaling, {\it tx\/} and {\it ty\/} are for translation,
  485. and {\it rot\/} is for counter-clockwise rotation (in degrees).
  486.  
  487. \item[thick] is the integer thickness of the line. Usually between 1 and 12.
  488.  
  489. \item[vect] is the type of vector font to use. One of |C|, |H|, or |V|
  490. indicates circular, horizontal-flat, or vertical-flat pen type. Defaults to
  491. circular pen.
  492.  
  493. \item[style] is the line-style to use. One of |0|, |1|, |2|, or |3| indicates
  494. a solid, dotted, dashed, or dot-dashed line-style. Defaults to solid line.
  495.  
  496. \item[spltype] is the kind of spline to use through the control points. One of
  497. |B|, |D|, |K|, or |I| indicates the B-spline, Cardinal, Catmull-Rom, or
  498. Interpolating b-spline basis to use, respectively. Defaults to Catmull-Rom.
  499.  
  500. \item[closure] is one of |O| (``oh'') or |U| which indicates that the spline
  501. is closed or open, respectively. Defaults to open.
  502.  
  503. \item[numpts] is the integer number of control points for this spline.
  504.  
  505. \item[radius] is the length of the radius in units specified by \Prm{meas}.
  506.  
  507. \item[centx] and {\bf centy} are the center-point coordinates
  508.  of the arc/circle.
  509.  
  510. \item[startAng] and {\bf stopAng} are the initial and final angles,
  511. respectively, for the arc as measured in degrees counter-clockwise from the
  512. positive x-axis. If they are the same number, a closed circle is indicated.
  513.  
  514. \item[face] refers to the style of typeface for the label.
  515. See page~\pageref{labelfonts} for the list.
  516.  
  517. \item[string] is the string-body of the label to typeset at the specified
  518. position.
  519.  
  520. \item[staffsize] refers to the staff note-size for beams. It is between 0
  521. and 8, inclusive.
  522.  
  523. \item[beamtype] is the type of beam to use. One of |G| or |R| indicates
  524. grace-note size, or regular size beams, respectively. Defaults to regular.
  525.  
  526. \item[wid] and {\bf ht} refer to the width and height of a figure, in units
  527. specified by \Prm{meas}. Mainly used in conjuction with |F| (``Fitting''
  528. size operator) and |W| (``Written'' size marker).
  529. \end{description}
  530. \Makeodd
  531. E_O_F
  532. else
  533.   echo "will not over write ./doc/TYLMAN.09"
  534. fi
  535. chmod 644 ./doc/TYLMAN.09
  536. if [ `wc -c ./doc/TYLMAN.09 | awk '{printf $1}'` -ne 5644 ]
  537. then
  538. echo `wc -c ./doc/TYLMAN.09 | awk '{print "Got " $1 ", Expected " 5644}'`
  539. fi
  540. if `test ! -s ./doc/TYLMAN.07`
  541. then
  542. echo "writing ./doc/TYLMAN.07"
  543. cat > ./doc/TYLMAN.07 << 'E_O_F'
  544. \chapter{The Implementation}
  545. \section{Overview}
  546. \TT is currently nearly 9000 lines of Pascal code (not {\smallrm WEB}). It is
  547. a prototype, and {\it not} a product.
  548. Testing was simplified by the ability to pre-view\index{DVI file, previewing} the contents of the
  549. {\DVI} file on Sun workstations using the {\smallrm DVISUN}
  550. \index{DVISUN}\cite{dvisun} program. It was written using
  551. Berkeley Unix\footnote{Unix is a trademark of Bell Laboratories}\index{Unix} 
  552.  Pascal\index{Pascal}, but is not dependent on that operating system 
  553. except for
  554. differences in I/O. There are also differences in
  555. efficiency/ease of reading from files---{\tt read}s versus {\tt get}s.  I/O
  556. routines for both byte types (signed and unsigned)
  557.  are written and available, and have been set up
  558. for easy porting to other machines.\par
  559.  
  560. The idea for handling {\DVI} files is to read each byte
  561. into a buffer until we read an {\tt eop} (end-of-page marker), when we will
  562. write that buffer out into a file, and start a  fresh buffer with the next
  563. page. If we encounter a |\special| in our reading, we treat it as a
  564. \index{specials, handling}\index{macro-expansion}
  565. macro-expansion---substituting {\it our} byte-string for the byte-string
  566. that represented the invoked special, and put this ``tyled''\index{tyling} string into the
  567. buffer for subsequent output.  A nice feature of this slurping is the parser
  568. for the specials. It is simple and extensible enough to easily accommodate
  569. new \TT primitives, and different or additional parameters.\par
  570.  
  571. Besides being careful about the expansion of the |\special| string, \TT
  572. has to keep track of any newly-defined fonts for insertion into the
  573. {\tt postamble} in the  {\DVI} file, and do some bookkeeping for
  574. {\tt bop} backpointers, and file byte-length.\par
  575.  
  576. Most of this chapter discusses the
  577. algorithms and data-structures of \TT at various levels. 
  578. We'll start with the high-level and user concepts, and work our way down
  579. into the details of outputting the actual bytes into the {\tt .dvi} file.\par
  580.  
  581. \section{Primitives}
  582. The user's interface to \TT is through |.tex| text files.\index{{\tt .tex}
  583. text file}
  584. He types in the |\special| strings for {\TeX},\index{{\TeX}} 
  585. and fills in the name of the primitive to typeset
  586. and any parameters to modify the attributes of the
  587. primitive. This |.tex| file is converted by {\TeX} into a |.dvi| file which
  588. is then given to \TTN.
  589. \index{primitives, modifying attributes}
  590. For the most part, all of the graphic primitives\index{primitives}
  591.  in \TT have common attributes
  592. of\index{primitives, attributes}\label{prims-attribs}
  593. \begin{itemize}
  594. \item  bounding-box\index{bounding box},
  595. \item line thickness,
  596. \item pen-type (see section~\ref{vect-pens}),
  597. \item line style\index{line style}
  598. \end{itemize}
  599. that describe basic appearances of an item. A ``bounding-box''
  600. \index{bounding box} describes the
  601. minimum and maximum $X$ and $Y$ values of a minimum-sized
  602. orthogonal rectangle that encloses the primitive.
  603. I'll describe the primitives and
  604. point out their additional or modified attributes to those above. My plan
  605. was to provide a number of primitives that were conceptually built upon
  606. lower-level primitives, and share similar representations wherever possible.
  607. For example, a |tieslur| is clearly built upon the representation\index{tieslur, representation} of a
  608. spline primitive. With this concept, I was able to represent the following
  609. primitives and effectively ``draw'' them by reducing to easier primitives,
  610. \index{primitives, reduction of} down to the vector-font level.\par\filbreak
  611. \medskip
  612. \noindent{\bf Line}\par
  613. The most basic primitive is the |line|, as all other non-figure 
  614. primitives\index{line segments}\index{{\tt line}}
  615. reduce to the same routines that produce line-segments. A line has
  616.  attributes of bottom-left and upper-right endpoints,
  617. and is drawn from left to right in {\DVI}-space, which is similar to
  618. fourth-quadrant cartesian space, but $y$-values are positive-increasing going down the
  619. y-axis\index{DVI-space}. In section~\ref{vect-setting} I will describe how the line is
  620. ``drawn'' on the virtual page using the vector-font characters.\par
  621. \medskip
  622. \noindent{\bf Spline}\par
  623. The spline primitives (|spline| and |ttspline|) have the attributes of a
  624. \index{splines, attributes}
  625. line, and in addition:\index{{\tt spline}}\index{{\tt ttspline}}
  626. \begin{itemize}
  627. \item spline type (see section~\ref{splines}),
  628. \item openness, 
  629. \item a count, and a list of control-points.
  630. \end{itemize}
  631. The spline primitives all use the same basic algorithm for interpolation of
  632. its control-points (``knots'') using one of three spline bases: the B-spline
  633. basis, the Cardinal basis, and the Catmull-Rom basis. The difference is mainly
  634. in the choice of basis matrix.\index{splines, basis}\index{splines, B-spline}
  635. \index{splines, Catmull-Rom}\index{splines, Cardinal}\par
  636.  
  637. |Ttspline|s have an additional attribute that describes the thickness of the
  638. spline at each control point. \TT uses the same method of
  639. spline\index{{\tt ttspline}}
  640. interpolation for computing the varying thicknesses over the length of the
  641. spline as for computing the position of the line-segment positions over the
  642. spline.\par
  643. \medskip
  644. \noindent{\bf Ties}\par
  645. A |tieslur|\index{{\tt tieslur}} is just a subset of 
  646. ttsplines\index{tieslur, relation to ttsplines}. It has exactly $5$
  647. control-points,\index{tieslur, attributes}
  648. which is sufficient to describe even the longest slur. It needs two
  649. specified line thicknesses: (1) a minimum thickness value at the far end points,
  650. and (2) a maximum thickness in the middle of the slur. \TT uses an internal
  651. algorithm to figure the other thicknesses of the control points. This then
  652. reduces to a ttspline of five control points for interpolation. The only
  653. other difference from a |ttspline| is in the 
  654. ``clamping'' mechanism\index{splines, clamping}\index{clamping}\index{ttspline, clamping}\index{tieslur, clamping}.
  655.  Let me explain: optimally, we would like the smoothest possible transitions
  656. of line thicknesses along a varying thickness spline, but this is still
  657. subject to the aliasing artifacts
  658. (``stair-steps'',\ ``jaggies'')\index{jaggies} of the printing device's
  659. resolution (you can't have 3.3 pixels in black and white).  We could have a
  660. vector font for every possible pixel-size of the printer, and thus be able
  661. to achieve as smooth a line as the printer is capable. This could easily
  662. require the printer to use dozens of different fonts per page (imagine a
  663. page of math, text, and a complex figure) which most printers' limited font
  664. memories\index{output device, font memory} cannot handle\par
  665. We are faced with either not being able to  print the page (sort of
  666. defeating the whole purpose), or to reduce the number of fonts required to
  667. set that particular figure. This reduction is called ``clamping.'' We make
  668. sure that a requested vector size is in a pre-selected set of fonts, and
  669. then modify that size if it is not in that set. Usually this involves just
  670. adding/subtracting a vector-pixel unit and iterating again through the test-modify
  671. loop until the size fits.\par
  672.  
  673. Ties and slurs use the same basic clamping mechanism as |ttspline|s
  674. (described above), but also have a built-in way to select and compute the
  675. thicknesses along the length of the spline. This means that \TT decides the
  676.  thicknesses for the tie/slur using its own algorithm based on the user
  677. specifying the maximum and minimum thicknesses.\par
  678.  
  679. \medskip
  680. \noindent{\bf Arcs}\par
  681. |Arc|s \index{{\tt arc}} are described\index{arcs, attributes} in terms of a radius, an initial and
  682. final angle, and an optional  center coordinate. Internally, this is
  683. transformed into a uniform-thickness spline.\index{arcs, representation}
  684.   Closed circles are a special
  685. case\index{circles} of arcs,\index{circles, relation to arcs}
  686. \index{arcs, circles} and so we can pre-compute
  687. the  control points of the closed spline\index{arcs, closed splines} to describe the
  688. circle,\index{circles, control points} and then just scale to fit the desired
  689. radius and translate its center to the required coordinate. Ellipses,
  690. \index{arcs, ellipses} \index{ellipses} although not a named primitive, can
  691. be simulated effectively by specifying a closed arc (a.k.a\   circle) and
  692. \index{ellipses, relation to circles}
  693. transform it by scaling as desired in either $X$ and/or $Y$, since circles are a
  694. special case of ellipses.\par
  695.  
  696. Open arcs are represented by an open spline\index{arcs, open}\index{arcs, open spline} whose control
  697. points were computed\index{arcs, control points} by sampling along the length
  698. of the arc. We do this sampling in 16 places using the parametric
  699. representation of the arc:
  700. $$x = r \cos\theta \> {,}\>\> y = r \sin\theta \qquad 
  701. {\rm\ for\ } \alpha_1 \le \theta \le \alpha_2  $$ and
  702. $\theta$ is a multiple of ${1\over 16} (\alpha_2 - \alpha_1)$. After we obtain
  703. these control points, we can interpolate over the knots and obtain the
  704. spline segments.\par
  705.  
  706. In reality, we  have to treat arcs with a little more special care 
  707. than simple splines. In computing open splines, we have to do some tricks
  708. with the list of control points. We introduce ``phantom'' control
  709. points
  710. which help the endpoints look nicer. See \cite{wu-abel} for a better explanation
  711. of phantoms\index{phantom control points}. The problem with arcs is that the
  712. \index{arcs, phantoming}endpoints would look too ``flat'' if we used the normal phantom-ing method\index{phantoming}.
  713. What I do is to create two extra control points (one before the start of the
  714. actual arc, and one after) so that we preserve roundness by continuing
  715. around the arc with the same parameters to the representation. Then I {\it
  716. lie\/} to \TT 's innards, saying, ``these extra points are not really part
  717. of the arc to typeset. They are the phantoms, so don't compute any for
  718. us.''\index{lies} After that, everything else works pretty much the same as
  719. regular open-splines in ``tyl''-ing\index{tyling}. It should be apparent that splines are
  720. the largest class of primitive types that \TT deals with, since they are
  721. capable of simulating/representing most graphical objects that we ususally
  722. work with.\index{splines, use in simulating}\par
  723. \medskip
  724. \noindent{\bf Beams}\par
  725. The last basic primitive that \TT offers is the |beam|. Beams\index{{\tt beam}} are
  726. graphically equivalent to straight line-segments. The only difference
  727. is\index{beams, difference from lines}
  728. that they have a different font that they use. This font and the particular
  729. characters from it are determined by the beam's two attributes:\index{beams, attributes} staffsize
  730. and beam-type. Staff size refers to the spacing of the staff lines of
  731. a\index{staff sizes}\index{staff lines}
  732. music score, which also determines the size of the music symbols to use. It
  733. is analagous to defining the point size of a character given the interline
  734. spacing measure. See \cite{ross} for examples of each size, also the 
  735. discussion of the beam characters on page~\pageref{beam-chars-sizes}. The
  736. beam-type attribute refers to the size of notes that the beam connects:
  737. regular or grace notes. More will be said about beams in
  738. section~\ref{beam-setting}.\par
  739. \medskip
  740. \noindent{\bf Labels}\par
  741. |Label|s\index{{\tt label}} are not really considered primitives, but are included 
  742. here for convenience and completeness. They have no correspondence 
  743. with any of the other graphic-primitives described above, but may be
  744. included in figure definitions.
  745. Labels have the attributes of starting position, font-style, and 
  746. the string-body of the label. They are not transformable at the
  747. local level (but are affected by figure-level transforms),
  748.  and are basically pretty simple in nature. {\TeX} macros are not expanded
  749. within the string-body by \TTN; you should use {\TeX} do to any
  750. smarter label-typesetting.\par
  751. Currently, the built-in list of fonts selectable for
  752.  use\index{fonts, for labels}\index{labels, font face-styles} in placing
  753. labels is:\label{labelfonts}
  754. \begin{itemize}
  755. \item amtt10 (selectable by specifying face |1|)
  756. \item amb10 (face |2|)
  757. \item amsl10 (|3|)
  758. \item amtt8 (|4|)
  759. \item and amsl8 (|5|) 
  760. \end{itemize}
  761. The characters from these fonts are simply set, as \TT does not 
  762. worry about kerning or ligatures, and spacing is done with 
  763. information found in the parameter section of the |.tfm| file.
  764.  This font mapping list is only temporary, and 
  765. can be changed  within the \TT source program.\par
  766.  
  767. \section{Procedural Handling}\label{proc-handling}
  768. After \TT picks apart the |\special| strings\index{special} from the {\DVI} file,
  769. and determines the parameters (both specified and defaulted) for the specified 
  770. primitive, \TT makes a note about where in the file the start of the special
  771. occurs, and passes the data to a {\it handler}.\index{handlers} A handler is
  772. a procedure that is specific to each primitive (e.g., there is a
  773. |linehandle|,\index{handlers, linehandle} and a |ttsplinehandle|
  774. procedure\index{handlers, ttsplinehandle}) that knows about the internal
  775. representation of each primitive, and how to ``handle'' the data passed to
  776. it. We'll talk more about the internal representation in the next
  777. section.\par
  778.  
  779. The handlers' primary responsibility is to take care of primitive-level
  780. geometric transformations, and then to decide what to do with the data,
  781.  depending on the context of\index{handlers, functionality}
  782. the primitive being dealt with. This context is determined by whether the
  783. primitive is contained in a figure, or is by itself. If the primitive is
  784. {\it not}
  785. contained in a figure (i.e., the |\special| string was not within a
  786. |beginfigure| -- |endfigure| pair), the handler 
  787. \begin{enumerate}
  788. \item computes the bounding box for the primitive\index{bounding box},
  789. \item transforms the
  790. coordinates of the primitive into {\DVI}-space\index{DVI-space},
  791. \item offsets them by the current position on the page,
  792. \item outputs a {\DVI} |push| command,\index{{\tt push}}
  793. \item calls an appropriate procedure to actually typeset the primitive,
  794. \item and finishes with a |pop| command.\index{{\tt pop}}
  795. \end{enumerate}
  796. We need to transform coordinates from our first-quadrant cartesian space
  797. into {\DVI}-space because the lower-level procedures that actually
  798. typeset and output the vector characters assume that they are putting the
  799. characters onto a page of the {\DVI} file.\index{transform to DVI space}\par
  800.  
  801. If the primitive's definition is part of an enclosing figure definition, we
  802. delay output of this primitive until the figure is completely defined. The
  803. handler does any simple geometric transformations required, and then
  804.  simply packs the data into another structure, and sort of ``stacks'' this
  805. new structure (let's call it an {\it item}\index{item}) onto a list of items
  806. that are contained in this figure.  Our reference to ``figure''
  807. here could also be a sub-figure within an enclosing figure, but for now
  808. we'll just deal with primitives in terms of simple, one-level figures. When
  809. the figure definition is complete, the |figurehandle|
  810. procedure\index{handlers, figurehandle} is called. We will get into figures
  811. more in the next section, but for now, we'll say that this handler
  812. \begin{enumerate}
  813. \item computes the bounding box of all the sub-items of this figure, 
  814. taking care of necessary transformations,
  815. \item outputs a |push| command,
  816. \item unpacks each sub-item, and transforms its coordinates into {\smallrm
  817. DVI}-space,
  818. \item calls the item's particular primitive handler with a special flag
  819. that says to simply call the appropriate procedure for immediate typesetting
  820. without doing any further transforms,
  821. \item and finishes with outputting a |pop| command to the {\DVI}
  822. file.
  823. \end{enumerate}
  824. The design of these handlers was to maintain the idea
  825. of\index{handlers, design idea}
  826. ``information-hiding'' such that each handler (primitive-  or figure-level)
  827. would know only about one level of abstraction below it.\par
  828.  
  829. \section{Figures}
  830. Let's look more closely at what we called ``items'' \index{item}in the previous section,
  831. and how we really represent figures. Up to this point, I have been rather
  832. ambiguous when referring to ``primitives.''\index{primitives, definition of} In some cases, it meant
  833. {\it graphic-primitives\/} (like lines and splines); in other cases it meant
  834. {\it the things that we can make pictures with\/} (like figures, sub-figures,
  835. and graphic-primitives). Well, now the ambiguity gets worse. I'll try to be
  836. careful about distinguishing ``graphic-primitives'' when I mean  primitives that
  837. are reducible to vector characters, and use ``primitives'' when I mean
  838. graphic-primitives {\it and\/} figures. The reason for
  839. the difference is that since we have the ability to do recursive sub-figure
  840. definitions, a ``figure'' (as denoted by a |beginfigure|--|endfigure| pair)
  841. becomes a building block (just like graphic-primitives) for
  842. that enclosing figure's definition.  It is analagous to the programming
  843. language concept of \Prm{block}, where (in BNF notation)
  844. \vspace*{-10pt}\begin{verbatim}
  845.  <figure> ::= <primitive> / <primlist>
  846.  <primlist> ::= <beginfigure> <primlist> <endfigure> /
  847.                 <primitive> <primlist> /   <empty>
  848. \end{verbatim} 
  849. where \Prm{primitive} is what we previously referred
  850.  to as an ``item,''\Prm{beginfigure} is
  851.  denoted by |\special{tyl beginfigure}|, and
  852. \Prm{endfigure} is denoted by |\special{tyl endfigure}|.  Refer back
  853. to page~\pageref{sub-figures} for an example of sub-figures.\par
  854.  
  855. \medskip
  856. \noindent{\bf Items}\par
  857. The ``item'' data structure contains the attributes for graphic-primitives,
  858. as outlined in section~\ref{prims-attribs}, and also contains 
  859. attributes for a figure like:
  860. \begin{itemize}
  861. \item any figure-level transformation parameters,
  862. \item a ``name,''
  863. \item and the list of items contained in this figure.
  864. \end{itemize}
  865. As you may surmise, this can yield a linked-list of linked-lists when built
  866. to represent a complex nested figure. In our previous discussion of
  867. handlers, one mode of their operation was to ``pack and stack'' the data
  868. into an item. Packing\index{item, packing} is easy enough to understand, but putting this
  869. structure in the correct place is tricky. When an item is created and filled
  870. with the appropriate parameters in a graphic-primitive's handler, there is a
  871. notion of ``context''\index{figures, context} which refers to the depth of recursion
  872. of sub-figures. A depth of $0$ means that there is no higher-level figure, a
  873. depth of $1$ means that any primitives encountered will belong to an
  874. outermost level figure, etc. When \TT comes across a |beginfigure| special
  875. string, it changes the recursive-definition context, and names that figure
  876. with that depth number. After that, any graphic-primitives that are
  877. encountered belong to that named figure in that context. An |endfigure|
  878. special will decrement the depth of recursion, and thus will change context
  879. back to the previous context. If this new context has a depth of $0$, then
  880. we know we have closed the outermost level of figure definition, and thus
  881. we are ready to typeset the entire figure.\par
  882.  
  883. Let's look at how items are inserted\index{item, inserting} onto our data structure so that context
  884. is maintained. \TT uses a procedure called |pushItem| that takes an item and
  885. puts it on the correct list (or sub-list) according to the current figure
  886. context. Roughly, the algorithm is a simple insert, based on a key of
  887. depth-name.
  888. \begin{tabbing}
  889. \hskip 1cm \= Start from the front of the list of this figure\\
  890.   \> while \= the list is not empty\\
  891. \>    \> Look \= at the item\\
  892. \>    \>     \> if it is \= a figure of the current context\\
  893. \>    \>    \>\> then we are done searching. do an insert\\
  894. \>    \>    \> otherwise {\it there must be a sub-figure lower on the
  895. list}\\
  896. \>    \>    \> \> look for the next item on the list that is a figure\\
  897. \>    \>    \> \> and start the next search from its list
  898. \end{tabbing}
  899. I really simplified the explanation of the
  900. insertion scheme here, but the important idea is that of looking for the
  901. correctly labelled figure-list and inserting the item there.\par
  902.  
  903. Once the structure is built, and \TT determines that it is ready to typeset
  904. the entire figure, it traverses\index{item, traversing} the structure to compute and note the
  905. bounding boxes of the sub-figures (and their bounding boxes, too).\index{bounding
  906. box}
  907.  We need to do this in case there are any\index{transforms, figure-level}
  908. figure-level scaling or rotations of graphic-primitives which are performed relative
  909. to the center of the bounding box of the primitives contained in the 
  910. figure. As we traverse the sub-figures, we do any required sub-figure
  911. transforms, record the dimensions of the bounding box, and pop up a level.
  912. When our traversal has reached the top level, all the figure's primitives
  913. have been transformed according to the recursive definition's specifications
  914. (i.e., the transforms are additive as we descend in recursive 
  915. depth).\index{transforms, additiveness}  If there are any top-level transforms
  916. to be taken care of,\index{transforms, top-level} we revisit the lists of
  917. primitives, performing the transforms.
  918. Finally, at
  919. this point we are ready to re-traverse the structure, grab each
  920. graphic-primitive, unpack it, transform it into {\DVI}-space, 
  921. and give control to its handler for immediate typesetting.\par
  922.  
  923. If you really want to get picky, the contents of a figure are not
  924. typeset and output until the last balancing |endfigure|\index{{\tt endfigure}} is encountered. It
  925. is at the current position on the page where this |endfigure| is set that
  926. the origin of our figure is placed. We can get away with this condition
  927. because specials are viewed by {\TeX} as ``boxes'' of zero width, and so a consecutive series of
  928. |\special|s do not change the current position on the page relative to the
  929. first invocation of the list. If, however, the user types in normal
  930. {\TeX}-typesettable text in the middle of a list of |\special|s defining a 
  931. figure, the current position will move, and our figure will be shifted down
  932. to the position where the final |endfigure| is invoked. This might make him
  933. unhappy. My advice is to think of the figure/picture as an atomic entity,
  934. whose contents is strictly a list of |\special| strings defining that
  935. figure.\par
  936.  
  937.  
  938. \section{The Fonts}
  939. The whole basis of this program lies in the ability to typeset graphics with
  940. characters. Thus we have two families of fonts: the vector fonts (originally
  941. designed at C-MU\cite{nelson-saxe} by Bruce Lucas\index{Lucas{,} Bruce}),
  942.  and the beam fonts (part of the music
  943. fonts for the {\it MusiCopy\/}\index{MusiCopy} project).\par
  944.  
  945. \TT converts the requests for line-drawings into commands to typeset these
  946. characters of line segments. See Appendix~\ref{font-examples} 
  947. for examples of these characters. Since Metafont~79\index{Metafont} limits the {\smallrm
  948. TFM} information to 16 heights and depths, we have to do the computations of
  949. the character dimensions ourselves.\index{fonts, computing dimensions of}
  950.  This is easy to do as \TT has the
  951. correct dimensions for each character described in Pascal code in such a way
  952. that only a couple parameters from the {\tt .tfm} file need to be accessed
  953. in order for the code to define the exact (internal) dimensions for a font.
  954. In essence, the basic description of the vector and beam fonts are
  955. hard-coded in \TTN , in a manner independent of the actual size of the 
  956. pens used to draw them.
  957. This ``on-the-fly'' font calculation is done only as needed, and then the
  958. font information is cached and noted so that future requests for that font
  959. will not require us to re-compute these dimensions.\par
  960.  
  961. Within the modified {\DVI} file,
  962. \TT defines these new fonts and begins numbering from 300,\index{fonts,
  963. numbering} as a sort of
  964. ``signature.''\index{{\TT}, signatures} So if you look at this new 
  965. {\DVI} file with {\smallrm DVI}type, you can tell the parts that are typeset
  966. figures by noting the places in the listing that reference a font numbered
  967. above 300.\par
  968.  
  969. \subsection{Vector Setting}\label{vect-setting} The vector fonts themselves,
  970. as described in section~\ref{vectors}, are typeset using the method
  971. described by Nelson\cite{nelson-saxe}, and I'll describe how \TT does it. In
  972. section~\ref{proc-handling}, we made mention that a graphic-primitive's
  973. handler call an ``appropriate procedure to actually typeset the primitive.''
  974. This typesetting procedure is actually the ``hook''\index{programmer's hook}
  975. for a programmer to get right to the typesetting code. The procedures look
  976. like |Tyl|$x$, where $x$ is a graphic primitive (e.g., |TylSpline|,
  977. |TylArc|, etc.), and take as parameters the information equivalent to the
  978. unpacked representation of an item.  The coordinates of any points
  979. used are in {\DVI}-space, \index{DVI-space} and in units of
  980. scaled-points. Refer to the code for the formal parameter
  981. list of each |Tyl|$x$  procedure. These hooks call procedures to ``lay''
  982. line-segments
  983. on the page, after doing some work of clamping\index{clamping}, and opening
  984. the correct font files for the requested
  985. line-thickness\index{line thickness} (thickness{\underbar es} in the case
  986. of |ttspline|s). These procedures, in turn, call |layline|,\index{{\tt
  987. layline}} a procedure that determines the best way to typeset the
  988. line-segment.  |Layline| checks to see if the line is strictly horizonal or
  989. vertical so that it can reduce the line to typsetting a {\TeX} rule, and
  990. then just add endpoints for smooth overlap. However, if the line is more
  991. diagonal, we have to go through more work.\par
  992.  
  993. Diagonal lines, and certain cases where we think using {\TeX} rules 
  994. inappropriate, require potentially using the full set of vector characters. 
  995. The |diagonal| procedure intersects the line-segment with the origin of 
  996. the semi-square 
  997. of the vector font (see also page~\pageref{semisquare}). In essence, it
  998. implements a greedy method by scaling down the radius of the semi-square to find
  999. the longest possible radius of the vector characters such that the far point
  1000. of the line-segment lies just outside that radius.\par
  1001. \noindent
  1002. \begin{figure}[h]\hskip 4cm\begintyl{8cm}[1in]
  1003. \special{tyl beginfigure}
  1004. \special{tyl line m 2 0 70 32 70}
  1005. \special{tyl line m 2 32 70 32 6}
  1006. \special{tyl line m 2 0 6 32 6}
  1007. \special{tyl line m 2 0 55 16 55}
  1008. \special{tyl line m 2 16 55 16 22}
  1009. \special{tyl line m 2 16 22 0 22}
  1010. \special{tyl line m 2 0 46 8 46}
  1011. \special{tyl line m 2 8 46 8 30}
  1012. \special{tyl line m 2 0 30 8 30}
  1013. \special{tyl line m 2 0 42 4 42}
  1014. \special{tyl line m 2 4 42 4 34}
  1015. \special{tyl line m 2 0 34 4 34}
  1016. \special{tyl line m 2 0 40 2 40}
  1017. \special{tyl line m 2 2 40 2 36}
  1018. \special{tyl line m 2 0 36 2 36}
  1019. \special{tyl line m 2 0 38 32 38}
  1020. \special{tyl line m 8 0 38 25 54}
  1021. \special{tyl endfigure}\endtyl
  1022. \caption{Semi-squares of the Vector Fonts}
  1023. \end{figure}
  1024. \noindent Then |diagonal|
  1025. determines the $dy$ and $dx$ from the current position to that intersection
  1026. point on the line.\footnote{Thus $dx$ and $abs(dy)$ are integer powers of 2 
  1027. between 0 and 16 inclusive.}
  1028.   We use the mapping \index{vector font, mapping function}
  1029. function similar to \cite{nelson-saxe} to determine character code corresponding to these
  1030. $dy$ and $dx$ values:\goodbreak
  1031. \vspace*{-10pt}
  1032. $$ code = 160 + dy + dx - 9*{\rm max}\,(dx,\, -dy)\qquad {\rm\ for\ } dy < 0 \> {,
  1033. }\>\> dx \geq 0$$
  1034. $$ code = 160 + dy - dx - 7*{\rm max}\,(dx,\, dy)\qquad {\rm\ for\ } dy \geq 0 \> {,
  1035. }\>\> dx \geq 0$$
  1036. but this scheme assumes that our font has at least 160 characters (i.e.,
  1037. 256), but most fonts have only 128 characters. We have to re-map this 
  1038. discontinuous set of codes to fit with a range of $0 \ldots 127$, and in doing so,
  1039. we have to lie\index{lies} about two of the characters by pretending that
  1040. the two longest vertical vectors do not exist, but each is
  1041.  to be replaced by {\it two\/} vectors of half that length.\par
  1042.  
  1043. Once we have determined the vector character, all we have to do is move to the
  1044. current-position, set the character, increment our position, 
  1045. and finish setting the rest of this line-segment.  The
  1046. thickness of the vector theoretically does not matter, as the path followed
  1047. by the vector character is invariant over the thickness (at least to the
  1048. resolution of the printer).\index{vector font, path invariance}\par
  1049.  
  1050. \subsection{Beam Setting}\label{beam-setting}
  1051. The way that \TT typesets beam is similar to typesetting
  1052. line-segments.\index{beams, typesetting}
  1053.  The
  1054. |TylBeam| procedure  takes care of determining the correct beam character to
  1055. use. Recall from section~\ref{beam-chars-sizes} that there are two lengths
  1056. for each type of quarternote (i.e., regular notes and grace notes). When \TT
  1057. tries to typeset the beam, it uses the beam character whose length is
  1058. longest {\it and\/} whose angle is closest to that required.\par
  1059.  
  1060.  Given a music font of beam characters with their lengths, heights, depths,
  1061. and angles from horizontal computed, we try to set the whole beam at once by
  1062. the following method:
  1063. \begin{enumerate}
  1064. \item Compute the $dy$ and $dx$ of the beam, as well as its length and
  1065. actual angle from horizontal
  1066. \item compute the fractional number of characters needed to typset the beam
  1067. for both sizes of beam characters (this is
  1068. ${{\rm length}_{\rm beam}\over {{\rm length}_{\rm beamchar}}}$)
  1069. \item try to bracket a pair of beam characters whose angles are nearest the
  1070. actual angle of the beam
  1071. \item use the beam character that has the smallest angular deviation from
  1072. that of the actual beam
  1073. \item typeset the  characters along the line from the left
  1074. endpoint of the beam to as close to the right endpoint as possible. Then
  1075. typeset the last character such that the right-hand-side of the character
  1076. coincides with the right endpoint of the beam.
  1077. \end{enumerate}
  1078.  We only need to select one character to use for typesetting as the
  1079. slope of the beam is constant over its length, and the character used has a
  1080. ``slope'' (angle from horizontal) that is as close as possible to the
  1081. beam.\par
  1082. This juggling of ``best-length'' versus ``best-slope'' is only necessary
  1083. because of the need to keep the set of characters to a reasonable size, and
  1084. also because the angles required for beams is not as broad as for the
  1085. requirements of the more-general vector line-segments.\par
  1086.  
  1087. \section{Buffering}
  1088. As \TT reads in  bytes from the {\DVI} file for subsequent interpretation, it
  1089.  copies them
  1090. into an internal buffer. At a simple level, this buffer is used to simply
  1091. copy the {\DVI} bytes used on a {\DVI} page (delimited by |bop| and |eop|
  1092. bytes). Thus, \TT would act simply as a mechanism that copies its input to
  1093. its output, verbatim. At the level that {\it we} are interested in, this
  1094. buffer will hold all the bytes up to, and including  a |tyl| special string. 
  1095. On page~\pageref{proc-handling}, we made mention of a ``note about where the
  1096. start of the special occurred'' in the {\DVI} file. When we read
  1097. a\index{specials}\index{tyling}
  1098. |special|, we mark the position of the beginning byte of the special, as
  1099. found in our buffer. If we find that the special is ``tyl''-able, we back up
  1100. the current place in the buffer to the start of the special, and proceed
  1101. with the tyling. \TT will output typesetting command bytes, and effectively
  1102. over-write the previous |special| string in the buffer, achieving a kind of
  1103. in-line macro-ex